#ifndef __queue_H__
#define __queue_H__

#include <assert.h>
#include <stdlib.h>
#include "types.h"

#define enqueue(queue, val) \
{ \
    typeof(*(queue)->head) *new_item; \
    do { \
        new_item = malloc(sizeof(*new_item)); \
        assert(new_item && "Could not allocate memory for new queue entry."); \
        new_item->value = (val); \
        new_item->next = NULL; \
        if ((queue)->tail != NULL) \
            (queue)->tail->next = new_item; \
        (queue)->tail = new_item; \
        if ((queue)->head == NULL) (queue)->head = new_item; \
    } while(0); \
}

#define dequeue(queue, val) \
{ \
    if ((queue)->head != NULL) { \
        typeof(*(queue)->head) *head; \
        head = (queue)->head; \
        *(val) = head->value; \
        (queue)->head = head->next; \
        do { \
            head->value = 0; \
            head->next = NULL; \
            free(head); \
        } while(0); \
    } \
}

#define queue_free(queue) \
{ \
    if ((queue)->head != NULL) { \
        typeof(*(queue)->head) *head; \
        do { \
            for(;(queue)->head;) { \
                head = (queue)->head->next; \
                (queue)->head->value = 0; \
                (queue)->head->next = NULL; \
                free((queue)->head); \
                (queue)->head = head; \
            } \
            (queue)->tail = NULL; \
        } while(0); \
    } \
}

#endif //__queue_H__